/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ldap_comm.c                                        */
/*  NOTE      =                                                    */
/*  DATE      = 2015/07/27 by geyh                                 */
/*******************************************************************/
#include<stdio.h>
#include<stdlib.h>

#include"frmem.h"
#include"frcomm.h"
#include"frbyte_buffer.h"
#include"frlist.h"
#include "frreport_comm.h"
#include"ldap_comm.h"


#define LDAP_REPORT_KEY_REQ                             APM_REPORT_KEY_REQ".ldap"
#define LDAP_REPORT_KEY_RESP                            APM_REPORT_KEY_RESP".ldap"


#define LDAP_REPORT_KEY_PROTO_REQ                       LDAP_REPORT_KEY_REQ".ProtocolOP"
#define LDAP_REPORT_KEY_SCOPE_REQ                       LDAP_REPORT_KEY_REQ".scope"
#define LDAP_REPORT_KEY_DEREF_REQ                       LDAP_REPORT_KEY_REQ".derefAliases"
#define LDAP_REPORT_KEY_FILTER_REQ                      LDAP_REPORT_KEY_REQ".filter"
#define LDAP_REPORT_KEY_PRESENT_REQ                     LDAP_REPORT_KEY_REQ".present"
#define LDAP_REPORT_KEY_ATTR_DES_REQ                    LDAP_REPORT_KEY_REQ".attributeDesc"
#define LDAP_REPORT_KEY_ATTR_VAL_REQ                    LDAP_REPORT_KEY_REQ".attributevalue"
#define LDAP_REPORT_KEY_AUTH_REQ                        LDAP_REPORT_KEY_REQ".authentication"
#define LDAP_REPORT_KEY_ASSERT_REQ                      LDAP_REPORT_KEY_REQ".assertionValue"
#define LDAP_REPORT_KEY_ABANDON_REQ                     LDAP_REPORT_KEY_REQ".abandonRequest"
#define LDAP_REPORT_KEY_MSG_ID_REQ                      LDAP_REPORT_KEY_REQ".MessageId"
#define LDAP_REPORT_KEY_TYPE_REQ                        LDAP_REPORT_KEY_REQ".type"
#define LDAP_REPORT_KEY_OPERAT_REQ                      LDAP_REPORT_KEY_REQ".operation"
#define LDAP_REPORT_KEY_VALUE_REQ                       LDAP_REPORT_KEY_REQ".vals"
#define LDAP_REPORT_KEY_ENTRY_REQ                       LDAP_REPORT_KEY_REQ".entry"
#define LDAP_REPORT_KEY_OBJECT_REQ                      LDAP_REPORT_KEY_REQ".object"
#define LDAP_REPORT_KEY_VERSION_REQ                     LDAP_REPORT_KEY_REQ".version"
#define LDAP_REPORT_KEY_DEL_REQ                         LDAP_REPORT_KEY_REQ".delRequest"
#define LDAP_REPORT_KEY_NEWRDN_REQ                      LDAP_REPORT_KEY_REQ".newrdn"
#define LDAP_REPORT_KEY_DEL_OLDRDN_REQ                  LDAP_REPORT_KEY_REQ".deleteoldrdn"
#define LDAP_REPORT_KEY_NEW_SUPER_REQ                   LDAP_REPORT_KEY_REQ".newSuperior"
#define LDAP_REPORT_BASE_OBJ_SUPER_REQ                  LDAP_REPORT_KEY_REQ".baseobject"
#define LDAP_REPORT_SIZE_LIMIT_REQ                      LDAP_REPORT_KEY_REQ".sizelimit"
#define LDAP_REPORT_TIME_LIMIT_REQ                      LDAP_REPORT_KEY_REQ".timelimit"
#define LDAP_REPORT_TYPES_ONLY_REQ                      LDAP_REPORT_KEY_REQ".typesOnly"


#define LDAP_REPORT_KEY_PROTO_RESP                      LDAP_REPORT_KEY_RESP".ProtocolOP"
#define LDAP_REPORT_KEY_MSG_ID_RESP                     LDAP_REPORT_KEY_RESP".MessageId"
#define LDAP_REPORT_KEY_TYPE_RESP                       LDAP_REPORT_KEY_RESP".type"
#define LDAP_REPORT_KEY_OBJ_RESP                        LDAP_REPORT_KEY_RESP".objectName"
#define LDAP_REPORT_KEY_ATTR_RESP                       LDAP_REPORT_KEY_RESP".Attributevalue"
#define LDAP_REPORT_KEY_MATCH_DN_RESP                   LDAP_REPORT_KEY_RESP".matchedDN"




/*******************************************************************************
*  FUNC     :  获取ldap数据长度
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_lenth(Frbyte_Packet *p_packet, unsigned int *p_ui_length)
{
    int i_ret = 0;
    unsigned int ui_length = 0;
    int i_data_size = 0;

    if(p_packet == NULL || p_ui_length == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, 1, (uint32_t *)&ui_length, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //小于80
    if(ui_length <= 0x80)
    {
        *p_ui_length = ui_length;
        return FR_SUCC;
    }

    //如果大于80则表明长度位不止1位  获取长度位长度
    i_data_size = ui_length - 0x80;

    if(i_data_size > 4)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, i_data_size, (uint32_t *)&ui_length, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    *p_ui_length = ui_length;

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_skip_string(Frbyte_Packet *p_packet)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x04')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        i_ret = bytebuff_skip(p_packet, ui_str_len);
        return i_ret;
    }

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_skip_string1(Frbyte_Packet *p_packet)
{
    int i_ret = 0;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL)
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        i_ret = bytebuff_skip(p_packet, ui_str_len);
        return i_ret;
    }


    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取protocolOp
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_protocol(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, int *p_c_protocolOp)
{
    int i_ret = 0;
    unsigned char uc_tmp;

    if(p_packet == NULL || p_st_body_data == NULL || p_c_protocolOp == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //  ProtocolOP
    switch(uc_tmp)
    {
        case SEARCH_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "search");
            break;

        case MOD_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "modify");
            break;

        case ADD_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "add");
            break;

        case DEL_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "del");
            break;

        case MOD_DN_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "modDN");
            break;

        case COM_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "compare");
            break;

        case ABAND_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "abandon");
            break;

        case EXT_REQ:
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.op", "extended");
            break;

        default:
            *p_c_protocolOp = (int)uc_tmp;
            return FR_SUCC;
    }

    //添加节点
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    *p_c_protocolOp = (int)uc_tmp;

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取ldap  resp  code
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*           :  p_l_response_code            返回码
*           :  pp_response_string           返回值
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_resultCode(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_tmp = 0;
    unsigned char uc_tmp;
    unsigned int ui_size = 0;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x0a')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&ui_tmp, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = frreport_body_l7_add_long(p_st_body_data, APM_REPORT_KEY_RESP_CODE, ui_tmp);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(p_st_private)
    {
        if(ui_tmp != 0)
            p_st_private->i_flag_data_type = FRLOGIN_FAIL;
        else
            p_st_private->i_flag_data_type = FRLOGIN_SUCC;
    }

    switch (ui_tmp)
    {
        case 0:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "success");
            break;

        case 1:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "operationsError");
            break;

        case 2:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "protocolError");
            break;

        case 3:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "timeLimitExceeded");
            break;

        case 4:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "sizeLimitExceeded");
            break;

        case 5:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "compareFalse");
            break;

        case 6:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "compareTrue");
            break;

        case 7:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "authMethodNotSupported");
            break;

        case 8:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "strongAuthRequired");
            break;

        case 10:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "referral");
            break;

        case 11:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "adminLimitExceeded");
            break;

        case 12:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "unavailableCriticalExtension");
            break;

        case 13:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "confidentialityRequired");
            break;

        case 14:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "saslBindInProgress");
            break;

        case 16:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "noSuchAttribute");
            break;

        case 17:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "undefinedAttributeType");
            break;

        case 18:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "inappropriateMatching");
            break;

        case 19:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "constraintViolation");
            break;

        case 20:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "attributeOrValueExists");
            break;

        case 21:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "invalidAttributeSyntax");
            break;

        case 32:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "noSuchObject");
            break;

        case 33:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "aliasProblem");
            break;

        case 34:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "invalidDNSyntax");
            break;

        case 36:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "aliasDereferencingProblem");
            break;

        case 48:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "inappropriateAuthentication");
            break;

        case 49:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "invalidCredentials");
            break;

        case 50:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "insufficientAccessRights");
            break;

        case 51:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "busy");
            break;

        case 52:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "unavailable");
            break;

        case 53:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "unwillingToPerform");
            break;

        case 54:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "loopDetect");
            break;

        case 64:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "namingViolation");
            break;

        case 65:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "namingViolation");
            break;

        case 66:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "notAllowedOnNonLeaf");
            break;

        case 67:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "notAllowedOnRDN");
            break;

        case 68:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "entryAlreadyExists");
            break;

        case 69:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "objectClassModsProhibited");
            break;

        case 71:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "affectsMultipleDSAs");
            break;

        case 80:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "other");
            break;

        case 118:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "canceled");
            break;

        case 119:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "noSuchOperation");
            break;

        case 120:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "tooLate");
            break;

        case 121:
            i_ret = frreport_body_l7_add_str(p_st_body_data,APM_REPORT_KEY_RESP_CODE_STRING, "cannotCancel");
            break;

        default:
            return FR_FAIL;
    }

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  ldap_get_resultCode
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_resp_info(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = ldap_skip_string(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_string(p_packet, p_st_body_data, APM_REPORT_KEY_RESP_ERR_MSG);

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取scope
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_scope(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned char uc_tmp;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x0a')
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x01')
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    p_st_private->i_scope = (int)uc_tmp;

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取derefAliases
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_derefAliases(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;
    unsigned char uc_tmp;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x0a')
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x01')
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    switch(uc_tmp)
//    {
//        case '\x00':
//            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_DEREF_REQ, "neverDerefAliases");
//            break;
//
//        case '\x01':
//            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_DEREF_REQ, "derefInSearching");
//            break;
//
//        case '\x02':
//            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_DEREF_REQ, "derefFindingBaseObj");
//            break;
//
//        case '\x03':
//            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_DEREF_REQ, "derefAlways");
//            break;
//
//        default:
//            return FR_FAIL;
//    }

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取filter
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_filter(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;
    char c_tmp;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&c_tmp);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    c_tmp = c_tmp & 0x0F;

    switch (c_tmp)
    {
        case '\x00':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "and");
            break;

        case '\x01':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "or");
            break;

        case '\x02':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "not");
            break;

        case '\x03':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "equalityMatch");
            break;

        case '\x04':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "substrings");
            break;

        case '\x05':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "greaterOrEqual");
            break;

        case '\x06':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "lessOrEqual");
            break;

        case '\x07':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "present");
            break;

        case '\x08':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "approxMatch");
            break;

        case '\x09':
            i_ret = frreport_body_l7_add_str(p_st_body_data, "request.ldap.param.filter", "extensibleMatch");
            break;

        default:
            return FR_FAIL;
    }

    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_tmp == '\x07')
    {
        i_ret = ldap_skip_string1(p_packet);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_tmp == '\x03')
    {
        i_ret = bytebuff_skip(p_packet, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = ldap_skip_string(p_packet);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = ldap_skip_string(p_packet);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_tmp == '\x00' || c_tmp == '\x01' || c_tmp == '\x02')
    {
        i_ret = ldap_skip_string1(p_packet);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        //todo
    }

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_string(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, const char *p_field_name)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    char *p_field_value = NULL;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x04')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        p_field_value = (char *)frmalloc(ui_str_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_packet, p_field_value, ui_str_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[ui_str_len] = '\0';

    }

    if(p_field_value)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
        frfree(p_field_value);
    }
    else
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, "\0");
    }

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_session_string(Frbyte_Packet *p_packet, char **pp_field_value)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    char *p_field_value = NULL;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL || pp_field_value == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x04')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        p_field_value = (char *)frmalloc(ui_str_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_packet, p_field_value, ui_str_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[ui_str_len] = '\0';
        if(*pp_field_value)
            frfree(*pp_field_value);
        *pp_field_value = p_field_value;
    }
    else
    {
        p_field_value = frstrdup("<root>");
        if(p_field_value == NULL)
            return FR_FAIL;

        *pp_field_value = p_field_value;
    }

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_user(Frbyte_Packet *p_packet, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    char *p_field_value = NULL;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL || p_st_private == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x04')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    p_field_value = (char *)frmalloc(ui_str_len + 1);
    if(p_field_value == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_packet, p_field_value, ui_str_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_field_value);
        return FR_FAIL;
    }
    p_field_value[ui_str_len] = '\0';

    p_st_private->p_user_name = p_field_value;
    fruuid(p_st_private->arr_session_id);

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_string1(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, const char *p_field_name)
{
    int i_ret = 0;
    char *p_field_value = NULL;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        p_field_value = (char *)frmalloc(ui_str_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_packet, p_field_value, ui_str_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[ui_str_len] = '\0';

    }

    if(p_field_value)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
        frfree(p_field_value);
    }
    else
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, "\0");
    }

    return FR_SUCC;

}


/*******************************************************************************
*  FUNC     :  获取字符串
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字符串名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_session_string1(Frbyte_Packet *p_packet, char **pp_field_value)
{
    int i_ret = 0;
    char *p_field_value = NULL;
    unsigned int ui_str_len = 0;

    if(p_packet == NULL || pp_field_value == NULL)
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_str_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_str_len)
    {
        p_field_value = (char *)frmalloc(ui_str_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_packet, p_field_value, ui_str_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[ui_str_len] = '\0';
        if(*pp_field_value)
            frfree(*pp_field_value);
        *pp_field_value = p_field_value;
    }

    return i_ret;

}



///*******************************************************************************
//*  FUNC     :  获取int
//*  ARGS     :  p_packet                     数据包
//*           :  p_ui_length                  出例长度
//*           :  p_field_name                 字段名
//*  RTN      :  FR_SUCC                      成功
//*           :  FR_FAIL                      失败
//*  NOTE     :
//*******************************************************************************/
//int ldap_get_int(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, const char *p_field_name)
//{
//    int i_ret = 0;
//    unsigned char uc_tmp;
//    int i_field_value = 0;
//    unsigned int ui_size = 0;
//
//    if(p_packet == NULL || p_st_body_data == NULL || p_field_name == NULL)
//        return FR_FAIL;
//
//    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
//    if(i_ret == FR_FAIL || uc_tmp != '\x02')
//        return FR_FAIL;
//
//    i_ret = ldap_get_lenth(p_packet, &ui_size);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    if(ui_size == 0)
//        return FR_FAIL;
//
//    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&i_field_value, BYTE_BIG_ENDIAN);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_field_value);
//
//    return i_ret;
//
//}


/*******************************************************************************
*  FUNC     :  获取int
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字段名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_skip_int(Frbyte_Packet *p_packet)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_size = 0;

    if(p_packet == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x02')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_size == 0)
        return FR_FAIL;

    i_ret = bytebuff_skip(p_packet, ui_size);

    return i_ret;

}

///*******************************************************************************
//*  FUNC     :  获取int
//*  ARGS     :  p_packet                     数据包
//*           :  p_ui_length                  出例长度
//*           :  p_field_name                 字段名
//*  RTN      :  FR_SUCC                      成功
//*           :  FR_FAIL                      失败
//*  NOTE     :
//*******************************************************************************/
//int ldap_get_int1(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, const char *p_field_name)
//{
//    int i_ret = 0;
//    int i_field_value = 0;
//    unsigned int ui_size = 0;
//
//    if(p_packet == NULL || p_st_body_data == NULL || p_field_name == NULL)
//        return FR_FAIL;
//
//    i_ret = ldap_get_lenth(p_packet, &ui_size);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    if(ui_size == 0)
//        return FR_FAIL;
//
//    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&i_field_value, BYTE_BIG_ENDIAN);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_field_value);
//
//    return i_ret;
//
//}

/*******************************************************************************
*  FUNC     :  获取int
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字段名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_skip_int1(Frbyte_Packet *p_packet)
{
    int i_ret = 0;
    unsigned int ui_size = 0;

    if(p_packet == NULL)
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_size == 0)
        return FR_FAIL;

    i_ret = bytebuff_skip(p_packet, ui_size);

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  获取boolean
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字段名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_boolean(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, const char *p_field_name)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_size = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x01')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL || ui_size != 1)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(uc_tmp == 0xff)
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, "true");
    else if(uc_tmp == 0x00)
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, "false");
    else
        return FR_FAIL;

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  获取boolean
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*           :  p_field_name                 字段名
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_skip_boolean(Frbyte_Packet *p_packet)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_size = 0;

    if(p_packet == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x01')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL || ui_size != 1)
        return FR_FAIL;

    i_ret = bytebuff_skip(p_packet, 1);

    return i_ret;

}

///*******************************************************************************
//*  FUNC     :  获取authentication   加密方式
//*  ARGS     :  p_packet                     数据包
//*           :  p_ui_length                  出例长度
//*           :  p_field_name                 字段名
//*  RTN      :  FR_SUCC                      成功
//*           :  FR_FAIL                      失败
//*  NOTE     :
//*******************************************************************************/
//int ldap_get_authentication(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
//{
//    int i_ret = 0;
//    int i_op = 0;
//
//    if(p_packet == NULL || p_st_body_data == NULL)
//        return FR_FAIL;
//
//    i_ret = bytebuff_get_int(p_packet, 1, (uint32_t *)&i_op, BYTE_BIG_ENDIAN);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    switch(i_op)
//    {
//        case 0x80:
//            i_ret = frreport_body_l7_add_str(p_st_body_data,LDAP_REPORT_KEY_AUTH_REQ,"simple");
//            break;
//
//        case 0x83:
//            i_ret = frreport_body_l7_add_str(p_st_body_data,LDAP_REPORT_KEY_AUTH_REQ,"sasl");
//            break;
//
//        case 0x90:
//            i_ret = frreport_body_l7_add_str(p_st_body_data,LDAP_REPORT_KEY_AUTH_REQ,"ntlmsspNegotiate");
//            break;
//
//        case 0x91:
//            i_ret = frreport_body_l7_add_str(p_st_body_data,LDAP_REPORT_KEY_AUTH_REQ,"ntlmsspAuth");
//            break;
//
//        default:
//            return FR_FAIL;
//
//    }
//
//    return i_ret;
//
//}


///*******************************************************************************
//*  FUNC     :  password 上报
//*  ARGS     :  p_packet                     数据包
//*           :  p_st_body_data                 链表
//*           :  p_i_mess_id                  message id
//*  RTN      :  FR_SUCC                      成功
//*           :  FR_FAIL                      失败
//*  NOTE     :
//*******************************************************************************/
//int ldap_get_password(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
//{
//    int i_ret = 0;
//    unsigned int ui_data_len = 0;
//
//    if(p_packet == NULL || p_st_body_data == NULL)
//        return FR_FAIL;
//
//    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
//    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
//        return FR_FAIL;
//
////    i_ret = frreport_body_l7_add_str()
////    p_st_node_data = frreport_mk_frdata_string("passWord", "******", 1);
////    if(p_st_node_data == NULL)
////        return FR_FAIL;
////
////    p_st_node = frlist_node_create(p_st_node_data);
////    if(p_st_node == NULL)
////    {
////        frfree(p_st_node_data->p_field_name);
////        frfree(p_st_node_data->p_field_value);
////        frfree(p_st_node_data);
////        return FR_FAIL;
////    }
////
//
//    return FR_SUCC;
//
//}



/*******************************************************************************
*  FUNC     :  获取message_id
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data                 链表
*           :  p_i_mess_id                  message id
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_message_id(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, int *p_i_mess_id, int i_use_request)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    int i_field_value = 0;
    unsigned int ui_size = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_i_mess_id == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x02')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);

    if(i_ret == FR_FAIL || ui_size == 0)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&i_field_value, BYTE_BIG_ENDIAN);
    *p_i_mess_id = (int)i_field_value;

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取attibutes
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_attibutes(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data,int i_use_request, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_data_len = 0;
    unsigned int ui_att_len = 0;
    int i_type = 1;
    int i_index = 0;
    char arr_tmp[64];

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

//todo  p_st_private->i_ret_rows

    //attibutes  30
    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x30')
        return FR_FAIL;

    //len
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    while(p_packet->ui_remaining)
    {
        i_ret = bytebuff_get_char(p_packet, &uc_tmp);
        if(i_ret == FR_FAIL || uc_tmp != '\x30')
            return FR_FAIL;

        i_ret = bytebuff_skip(p_packet, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        if(i_use_request)
        {
            snprintf(arr_tmp, sizeof(arr_tmp), "request.ldap.param.type.%d", i_type);
            i_ret = ldap_get_string(p_packet, p_st_body_data, arr_tmp);
            i_type++;
        }
        else
            i_ret = ldap_skip_string(p_packet);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = bytebuff_get_char(p_packet, &uc_tmp);
        if(i_ret == FR_FAIL || uc_tmp != '\x31')
            return FR_FAIL;

        i_ret = ldap_get_lenth(p_packet, &ui_att_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        while((int)ui_att_len)
        {
            //记录目前p_packet剩余长度
            ui_data_len = p_packet->ui_remaining;

            i_index++;
            if(i_use_request)
            {
                snprintf(arr_tmp, sizeof(arr_tmp), "request.ldap.param.%d", i_index);
                i_ret = ldap_get_string(p_packet, p_st_body_data, arr_tmp);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
            }
            else
            {
                i_ret = ldap_skip_string(p_packet);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
                p_st_private->i_ret_rows++;
            }

            ui_att_len -= (ui_data_len - p_packet->ui_remaining);
//            p_st_private->i_ret_rows++;
        }
    }

    i_ret = frreport_body_l7_add_int(p_st_body_data, "request.ldap.param.size", i_index);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

//    if(i_use_request == FR_NO)
//    {
//        i_ret = frreport_body_l7_add_int(p_st_body_data, "response.ldap.rows", p_st_private->i_ret_rows);
//        if(i_ret == FR_FAIL)
//            return FR_FAIL;
//    }

    return FR_SUCC;

}


/*******************************************************************************
*  FUNC     :  获取attibutes
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_attibutes1(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_data_len = 0;
    char arr_tmp[64];
    int i_index = 0;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    //attibutes  30
    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x30')
        return FR_FAIL;

    //len
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    while(p_packet->ui_remaining)
    {
        i_index++;
        snprintf(arr_tmp, sizeof(arr_tmp), "request.ldap.param.%d", i_index);
        i_ret = ldap_get_string(p_packet, p_st_body_data, arr_tmp);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    i_ret = frreport_body_l7_add_int(p_st_body_data, "request.ldap.param.size", i_index);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;

}

int ldap_get_mod_operation(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_size = 0;
    int i_tmp = 0;

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x30')
        return FR_FAIL;

    //len
    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL || ui_size != p_packet->ui_remaining)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x30')
        return FR_FAIL;

    //len
    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL || ui_size != p_packet->ui_remaining)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, &uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != '\x0a')
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&i_tmp, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch (i_tmp)
    {
        case 0:
            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_OPERAT_REQ, "add");
            break;

        case 1:
            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_OPERAT_REQ, "delete");
            break;

        case 2:
            i_ret = frreport_body_l7_add_str(p_st_body_data, LDAP_REPORT_KEY_OPERAT_REQ, "replace");
            break;

        //todo  其他值确认

        default:
            return FR_FAIL;
    }

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  获取modification
*  ARGS     :  p_packet                     数据包
*           :  p_ui_length                  出例长度
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_modification(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;
    unsigned char uc_tmp;
    unsigned int ui_data_len = 0;
    unsigned int ui_att_len = 0;
    int i_type = 1;
    int i_val = 0;
    char arr_tmp[64];

    if(p_packet == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    //operation  30
    i_ret = ldap_get_mod_operation(p_packet, p_st_body_data);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    while(p_packet->ui_remaining)
    {
        i_ret = bytebuff_get_char(p_packet, &uc_tmp);
        if(i_ret == FR_FAIL || uc_tmp != '\x30')
            return FR_FAIL;

        //len
        i_ret = ldap_get_lenth(p_packet, &ui_data_len);
        if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
            return FR_FAIL;

        snprintf(arr_tmp, sizeof(arr_tmp), "request.ldap.param.type.%d", i_type);
        i_type ++;

        i_ret = ldap_get_string(p_packet, p_st_body_data, arr_tmp);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = bytebuff_get_char(p_packet, &uc_tmp);
        if(i_ret == FR_FAIL || uc_tmp != '\x31')
            return FR_FAIL;

        i_ret = ldap_get_lenth(p_packet, &ui_att_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        while((int)ui_att_len)
        {
            //记录目前p_packet剩余长度
            i_val ++;

            ui_data_len = p_packet->ui_remaining;

            snprintf(arr_tmp, sizeof(arr_tmp), "request.ldap.param.%d", i_val);

            i_ret = ldap_get_string(p_packet, p_st_body_data, arr_tmp);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            ui_att_len -= (ui_data_len - p_packet->ui_remaining);
        }

        i_ret = frreport_body_l7_add_int(p_st_body_data, "request.ldap.param.size", i_val);
        if(i_ret == FR_FAIL)
            return FR_FAIL;


    }


    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  ldap_get_response
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_get_response(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_data_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    i_ret = ldap_get_resultCode(p_packet, p_st_body_data, p_st_private);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_resp_info(p_packet, p_st_body_data);

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  ldap_add_request
*  ARGS     :  p_packet                     数据包
*           :  p_lst_header
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_add_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
//    unsigned char uc_tmp;
    unsigned int ui_data_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    //entry
    i_ret = ldap_get_session_string(p_packet, &p_st_private->p_title);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //attibutes  30
    i_ret = ldap_get_attibutes(p_packet, p_st_body_data, FR_YES, p_st_private);

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  ldap_abandon_request
*  ARGS     :  p_packet                     数据包
*           :  p_lst_header
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_abandon_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{

    int i_ret = 0;
    int i_field_value = 0;
    unsigned int ui_size = 0;
    char arr_tmp[64];

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private ==NULL)
        return FR_FAIL;

    i_ret = ldap_get_lenth(p_packet, &ui_size);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_size == 0)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_packet, ui_size, (uint32_t *)&i_field_value, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_tmp, sizeof(arr_tmp), "%d", i_field_value);

    p_st_private->p_title = frstrdup(arr_tmp);
    if(p_st_private->p_title == NULL)
        return FR_FAIL;

    return FR_SUCC;

}


/*******************************************************************************
*  FUNC     :  ldap_modify_request
*  ARGS     :  p_packet                     数据包
*           :  p_lst_header
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_modify_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_data_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    i_ret = ldap_get_session_string(p_packet, &p_st_private->p_title);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_modification(p_packet, p_st_body_data);

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  ldap_bind_request
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_bind_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data , L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
//    unsigned char uc_tmp;
    unsigned int ui_data_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    //uuid
    fruuid(p_st_private->arr_session_id);

    //version
//    i_ret = ldap_get_int(p_packet, p_st_body_data, LDAP_REPORT_KEY_VERSION_REQ);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
    i_ret = ldap_skip_int(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //user name
    i_ret = ldap_get_user(p_packet, p_st_private);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

//    //authentication
//    i_ret = ldap_get_authentication(p_packet, p_st_body_data);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;
//
//    //password
//    i_ret = ldap_get_password(p_packet, p_st_body_data);
//    if(i_ret == FR_FAIL)
//        return FR_FAIL;

    return i_ret;

}



/*******************************************************************************
*  FUNC     :  ldap_del_request
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_del_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //resp info
    i_ret = ldap_get_session_string1(p_packet, &p_st_private->p_title);

    return i_ret;


}


/*******************************************************************************
*  FUNC     :  ldap_del_request
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_modDN_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_data_len = 0;
    unsigned char uc_tmp;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    //entry
    i_ret = ldap_get_session_string(p_packet, &p_st_private->p_title);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_string(p_packet, p_st_body_data, "request.ldap.param.1");
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //deleteoldrdn
    i_ret = ldap_get_boolean(p_packet, p_st_body_data, "request.ldap.param.2");
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_packet, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL || uc_tmp != 0x80)
        return FR_FAIL;

    //newsuperior
    i_ret = ldap_get_string1(p_packet, p_st_body_data, "request.ldap.param.3");
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = frreport_body_l7_add_int(p_st_body_data, "request.ldap.param.size", 3);

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  ldap_search_request
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_search_request(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_data_len = 0;
//    unsigned char uc_tmp;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    //baseobject
    i_ret = ldap_get_session_string(p_packet, &p_st_private->p_title);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //scope
    i_ret = ldap_get_scope(p_packet, p_st_body_data, p_st_private);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_derefAliases(p_packet, p_st_body_data);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //size limit
    i_ret = ldap_skip_int(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //time limit
    i_ret = ldap_skip_int(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //types only
    i_ret = ldap_skip_boolean(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_filter(p_packet, p_st_body_data);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_attibutes1(p_packet, p_st_body_data);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;

}



/*******************************************************************************
*  FUNC     :  ldap_search_done
*  ARGS     :  p_packet                     数据包
*           :  p_st_body_data
*  RTN      :  FR_SUCC                      成功
*           :  FR_FAIL                      失败
*  NOTE     :
*******************************************************************************/
int ldap_search_res_entry(Frbyte_Packet *p_packet, Frreport_body_data *p_st_body_data, L7session_ldap_private *p_st_private)
{
    int i_ret = 0;
    unsigned int ui_data_len = 0;

    if(p_packet == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //长度
    i_ret = ldap_get_lenth(p_packet, &ui_data_len);
    if(i_ret == FR_FAIL || ui_data_len != p_packet->ui_remaining)
        return FR_FAIL;

    i_ret = ldap_skip_string(p_packet);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = ldap_get_attibutes(p_packet, p_st_body_data, FR_NO, p_st_private);

    return i_ret;

}
